package com.fas.system.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fas.common.constant.Constants;
import com.fas.common.core.domain.AjaxResult;
import com.fas.common.core.redis.RedisCache;
import com.fas.common.utils.StringUtils;
import com.fas.system.domain.FasBuilding;
import com.fas.system.domain.FasBuildingImage;
import com.fas.system.domain.FasCooperationCompany;
import com.fas.system.domain.SysArea;
import com.fas.system.domain.vo.BuildingTree;
import com.fas.system.domain.vo.SysDeptVo;
import com.fas.system.mapper.FasBuildingImageMapper;
import com.fas.system.mapper.FasBuildingMapper;
import com.fas.system.service.IFasBuildingService;
import com.fas.system.service.IFasCooperationCompanyService;
import com.fas.system.util.OrderldUtil;
import com.fas.system.util.SendSmsUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 建筑公司Service业务层处理
 *
 * @author ruoyi
 * @date 2022-04-27
 */
@Service
public class FasBuildingServiceImpl implements IFasBuildingService {

    private static final Logger log = LoggerFactory.getLogger(SendSmsUtil.class);

    @Resource
    private FasBuildingMapper fasBuildingMapper;

    @Resource
    private RedisCache redisCache;
    @Resource
    private FasBuildingImageMapper fasBuildingImageMapper;
    @Resource
    private IFasCooperationCompanyService fasCooperationCompanyService;

    /**
     * 查询建筑公司
     *
     * @param id 建筑公司主键
     * @return 建筑公司
     */
    @Override
    public FasBuilding selectFasBuildingById(Long id) {
        return fasBuildingMapper.selectFasBuildingById(id);
    }

    /**
     * 查询建筑公司列表
     *
     * @param fasBuilding 建筑公司
     * @return 建筑公司
     */
    @Override
    public List<FasBuilding> selectFasBuildingList(FasBuilding fasBuilding) {
        List<FasBuilding> list = fasBuildingMapper.selectFasBuildingList(fasBuilding);
        list.forEach(ll -> ll.setCompanyName(FasCooperationCompanyServiceImpl.COMPANY_NAMES.get(ll.getCooperationCompanyId())));
        return list;
    }

    /**
     * 新增建筑公司
     *
     * @param fasBuilding 建筑公司
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertFasBuilding(FasBuilding fasBuilding) {
        // 检查建筑名是否重复
        int exists = fasBuildingMapper.existsByBuildingName(fasBuilding.getBuildingName());
        if (exists > 0) {
            return AjaxResult.error("建筑名称不能重复，请重新填写！");
        }
        // 生成建筑编号
        String buildingId = genBuildingId();
        fasBuilding.setBuildingId(buildingId);
        int count = fasBuildingMapper.insertFasBuilding(fasBuilding);
        // 生成建筑图纸
        generateBuildingImage(fasBuilding, count);
        return AjaxResult.success();
    }

    /**
     * 添加建筑时生成建筑图纸
     * @param fasBuilding
     * @param count
     */
    private void generateBuildingImage(FasBuilding fasBuilding, int count) {
        Integer undergroundNumber = fasBuilding.getUndergroundNumber();
        Integer abovegroundNumber = fasBuilding.getAbovegroundNumber();
        if (count > 0 && undergroundNumber != null && abovegroundNumber != null) {//添加建筑图纸表数据
            List<Integer> result = new ArrayList<>();
            for (int i = 1; i <= undergroundNumber; i++) {
                result.add(-i);
            }
            for (int i = 1; i <= abovegroundNumber; i++) {
                result.add(i);
            }
            Collections.sort(result);
            List<FasBuildingImage> buildingImageList = new ArrayList<>(result.size());
            for (Integer integer : result) {
                buildingImageList.add(new FasBuildingImage(fasBuilding.getId().intValue(), integer));
            }
            fasBuildingImageMapper.insertFasBuildingImage(buildingImageList);
        }
    }

    /**
     * 修改建筑公司
     *
     * @param fasBuilding 建筑公司
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateFasBuilding(FasBuilding fasBuilding) {
        int count = fasBuildingMapper.updateFasBuilding(fasBuilding);
        updateBuildingimage(fasBuilding, count);
        return count;
    }

    /**
     * 更新建筑图纸表
     */
    private void updateBuildingimage(FasBuilding fasBuilding, int count) {
        if (count > 0) {
            //查询原来的楼层数据层数
            List<Integer> dbFloorList = fasBuildingImageMapper.selectFloorList(fasBuilding.getId().intValue());
            Collections.sort(dbFloorList);
            Integer undergroundNumber = fasBuilding.getUndergroundNumber();
            Integer abovegroundNumber = fasBuilding.getAbovegroundNumber();
            // 现在的楼层层数
            List<Integer> floorList = new ArrayList<>();
            if (undergroundNumber != null && abovegroundNumber != null) {//添加建筑图纸表数据
                for (int i = 1; i <= Math.abs(undergroundNumber); i++) {
                    floorList.add(-i);
                }
                for (int i = 1; i <= abovegroundNumber; i++) {
                    floorList.add(i);
                }
                Collections.sort(floorList);
            }
            if (dbFloorList.size() == floorList.size() && dbFloorList.containsAll(floorList)) {
                return;
            }
            // 更新的楼层比之前少，删除多余的楼层
            if (dbFloorList.size() > floorList.size()) {
                dbFloorList.removeAll(floorList);
                // 删除建筑图纸表
                fasBuildingImageMapper.deleteFasBuildingImageByFloor(dbFloorList);
            } else {
                // 添加建筑图纸表
                floorList.removeAll(dbFloorList);
                List<FasBuildingImage> buildingImageList = new ArrayList<>(floorList.size());
                floorList.forEach(f -> buildingImageList.add(new FasBuildingImage(fasBuilding.getId().intValue(), f)));
                fasBuildingImageMapper.insertFasBuildingImage(buildingImageList);
            }
        }
    }

    /**
     * 批量删除建筑公司
     *
     * @param ids 需要删除的建筑公司主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteFasBuildingByIds(Long[] ids) {

        List<Long> existsIds = new ArrayList<>();
        int result = 0;
        if (ids.length > 0) {
            for (Long id : ids) {
                int exists = fasBuildingMapper.existsEquipmentOrFacility(id);
                if (exists > 0) {
                    existsIds.add(id);
                } else {
                    result += fasBuildingMapper.deleteFasBuildingByIds(ids);
                }
            }
            if (existsIds.size() > 0) {
                return AjaxResult.error("建筑下存在设施或者设备不能删除，建筑编号为：" + StringUtils.join(existsIds, ","));
            }
        }
        return result > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 删除建筑公司信息
     *
     * @param id 建筑公司主键
     * @return 结果
     */
    @Override
    public int deleteFasBuildingById(Long id) {
        return fasBuildingMapper.deleteFasBuildingById(id);
    }

    @Override
    public JSONArray findBuildingList(Long deptId, Integer buildingId, Integer facilitiesDistribution, Integer cooperationCompanyId,String buildingName) {
        List<BuildingTree> buildingList = fasBuildingMapper.findBuildingList(deptId, buildingId, facilitiesDistribution, cooperationCompanyId,buildingName);
        JSONArray jsonArray = new JSONArray();
        treeBuilding(buildingList, jsonArray);
        return jsonArray;
    }

    @Override
    public List<Integer> getBuildingFloor(Integer ids) {
        FasBuilding fasBuilding = fasBuildingMapper.selectFasBuildingById(ids.longValue());
        Integer undergroundNumber = fasBuilding.getUndergroundNumber();//地下层数
        Integer abovegroundNumber = fasBuilding.getAbovegroundNumber();//地上层数
        List<Integer> result = new ArrayList<>();
        for (int i = 1; i <= undergroundNumber; i++) {
            result.add(-i);
        }
        for (int i = 1; i <= abovegroundNumber; i++) {
            result.add(i);
        }
        Collections.sort(result);
        return result;
    }

    @Override
    public List<FasBuildingImage> findImageByBuildingId(Integer buildingId) {
        return fasBuildingImageMapper.findImageByBuildingId(buildingId);
    }

    @Transactional
    @Override
    public int updateFasBuildingImage(FasBuildingImage fasBuildingImage) {
        return fasBuildingImageMapper.updateFasBuildingImage(fasBuildingImage);
    }

    @Override
    public List<SysDeptVo> getDeptBuild(Integer cooperationCompanyId, Integer deptId) {
        List<FasBuilding> list = fasBuildingMapper.selectNotNullBuilding(cooperationCompanyId, deptId);
        //建筑中所有的单位id
        List<Integer> deptIds = list.stream().map(FasBuilding::getCooperationCompanyId).distinct().sorted().collect(Collectors.toList());

        List<SysDeptVo> companyList = new ArrayList<>();
        if (deptIds.size() > 0) {
            for (Integer companyId : deptIds) {
                SysDeptVo company = new SysDeptVo();
                company.setDeptId(companyId.longValue());
//                company.setDeptName(redisCache.getCacheObject(Constants.SYS_COMPANY_KEY + companyId));
                company.setDeptName(FasCooperationCompanyServiceImpl.COMPANY_NAMES.get(companyId));
                List<SysDeptVo> buildingList = new ArrayList<>();
                for (FasBuilding fasBuilding : list) {
                    if (fasBuilding.getCooperationCompanyId().equals(companyId)) {
                        SysDeptVo building = new SysDeptVo();
                        building.setDeptId(fasBuilding.getId());
                        building.setDeptName(fasBuilding.getBuildingName());
                        buildingList.add(building);
                    }
                }
                company.setChildren(buildingList);
                companyList.add(company);
            }
        }
        return companyList;
    }

    @Transactional
    @Override
    public AjaxResult importFasBuilding(List<FasBuilding> buildingList) {
        log.info("导入的建筑信息：" + buildingList);
        List<String> errorMsg = new ArrayList<>();
        List<FasBuilding> insertData = new ArrayList<>();
        // 合作单位数据
        List<FasCooperationCompany> fasCooperationCompanies = fasCooperationCompanyService.queryAll(new FasCooperationCompany());
        HashMap<Object, Object> companyNameMap = fasCooperationCompanies.stream().collect(HashMap::new, (m, e) -> m.put(e.getCompanyName(), e.getId()), HashMap::putAll);
        if (CollectionUtils.isEmpty(companyNameMap)){
            return AjaxResult.error("没有合作单位，请先添加合作单位");
        }
        //省市县redis缓存的数据
        List<SysArea> areaList = redisCache.getCacheObject(Constants.SYS_AREA_KEY);
        Map<String,String> map = new HashMap<>();
        for (SysArea sysArea : areaList) {
            map.put(sysArea.getName(),sysArea.getCode());
        }

        for (FasBuilding fasBuilding : buildingList) {
            String buildingName = fasBuilding.getBuildingName();
            int exists = fasBuildingMapper.existsByBuildingName(buildingName);
            if (exists > 0) {
                errorMsg.add(buildingName);
                continue;
            }
            // 生成建筑building_id
            String buildingId = genBuildingId();
            fasBuilding.setBuildingId(buildingId);
            //获取省编号
            String provinceCode = map.get(fasBuilding.getProvinceName());
            String cityCode = map.get(fasBuilding.getCityName());
            String areaCode = map.get(fasBuilding.getAreaName());
            String wayCode = map.get(fasBuilding.getWayName());
            if (StringUtils.isEmpty(provinceCode)){
                return AjaxResult.error("建筑名为 " + buildingName + "的省名称不对!" );
            }
            if (StringUtils.isEmpty(cityCode)){
                return AjaxResult.error("建筑名为 " + buildingName + "的市名称不对!" );
            }
            if (StringUtils.isEmpty(areaCode)){
                return AjaxResult.error("建筑名为 " + buildingName + "的区/县名称不对!" );
            }
            // 获取合作单位编号
            if (Objects.isNull(companyNameMap.get(fasBuilding.getCompanyName().trim()))){
                return AjaxResult.error("建筑名称为 " + buildingName+ " 的，合作单位名称错误，请检查");
            }
            Integer cooperationCompanyId = Integer.parseInt(String.valueOf(companyNameMap.get(fasBuilding.getCompanyName())));
            fasBuilding.setCooperationCompanyId(cooperationCompanyId);
            fasBuilding.setProvinceCode(provinceCode);
            fasBuilding.setCityCode(cityCode);
            fasBuilding.setAreaCode(areaCode);
            fasBuilding.setWayCode(wayCode);
            insertData.add(fasBuilding);
        }
        if (errorMsg.size() > 0) {
            return AjaxResult.error("重复的建筑名称，名称为: " + StringUtils.join(errorMsg, ","));
        }
        if (insertData.size() > 0) {
            int count = fasBuildingMapper.batchInsert(insertData);
            //生成建筑图纸
            insertData.forEach(d -> generateBuildingImage(d,count));
            return count > 0 ? AjaxResult.success() : AjaxResult.error();
        }
        return AjaxResult.error("导入的数据为空");
    }

    public void treeBuilding(List<BuildingTree> buildingList, JSONArray jsonArray) {

        for (BuildingTree fasBuilding : buildingList) {
            String provinceCode = fasBuilding.getProvinceCode();
            String cityCode = fasBuilding.getCityCode();
            String areaCode = fasBuilding.getAreaCode();
            String wayCode = fasBuilding.getWayCode();
            String provinceName = fasBuilding.getProvinceName();
            String cityName = fasBuilding.getCityName();
            String areaName = fasBuilding.getAreaName();
            String wayName = fasBuilding.getWayName();

            JSONObject wayJsonobject = new JSONObject();
            JSONArray jsonArray4 = new JSONArray();
            JSONArray dataArr = new JSONArray();
            dataArr.add(fasBuilding);
//            if (areaCode.equals("511322")){
//                System.out.println("1111111111111");
//            }
            if (wayCode != null) {
                wayJsonobject.put("code", wayCode);
                wayJsonobject.put("codeName", wayName);
                wayJsonobject.put("children", dataArr);
                jsonArray4.add(wayJsonobject);
            } else {
                jsonArray4.add(fasBuilding);
            }
            outer:
            // java 标号
            if (jsonArray.size() > 0) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject exists1 = existJSONArray(provinceCode, jsonArray);
                    //该省数据存在于数组中,添加市数据
                    if (exists1 != null && exists1.size() > 0) {
                        //取出所有市数据
                        JSONArray city_children = exists1.getJSONArray("children");
                        for (int i1 = 0; i1 < city_children.size(); i1++) {
                            // //该市数据存在于数组中,添加县数据
                            JSONObject exists2 = existJSONArray(cityCode, city_children);
                            //存在该市数据,添加县数据
                            if (exists2 != null && exists2.size() > 0) {
                                //拿到某个市数据下所有的县数据
                                JSONArray area_children = exists2.getJSONArray("children");
                                for (int i2 = 0; i2 < area_children.size(); i2++) {
                                    // //该市数据存在于数组中,添加县数据
                                    JSONObject exists3 = existJSONArray(areaCode, area_children);
                                    //存在该县数据，添加镇数据
                                    if (exists3 != null && exists3.size() > 0) {
                                        if (wayCode == null) {
                                            exists3.getJSONArray("children").addAll(jsonArray4);
                                            break outer;//添加了建筑数据后直接跳出循环
                                        } else {
                                            JSONArray way_children = exists3.getJSONArray("children");//所有镇的数据
                                            for (int i3 = 0; i3 < way_children.size(); i3++) {
                                                //存在镇数据
                                                JSONObject exists4 = existJSONArray(wayCode, way_children);
                                                if (exists4 == null || exists4.size() == 0) {
                                                    way_children.addAll(jsonArray4);
                                                } else {
                                                    exists4.getJSONArray("children").add(fasBuilding);
                                                }
                                                break outer;//添加了建筑数据后直接跳出循环
                                            }
                                        }
                                    } else {//增加县数据
                                        //区
                                        JSONObject jsonObject3 = new JSONObject();
                                        jsonObject3.put("code", areaCode);
                                        jsonObject3.put("codeName", areaName);
                                        jsonObject3.put("children", jsonArray4);
                                        area_children.add(jsonObject3);
                                        break outer;//添加了建筑数据后直接跳出循环
                                    }
                                }
                            } else { // 新增市数据
                                //区
                                JSONObject jsonObject3 = new JSONObject();
                                jsonObject3.put("code", areaCode);
                                jsonObject3.put("codeName", areaName);
                                jsonObject3.put("children", jsonArray4);
                                JSONArray jsonArray3 = new JSONArray();
                                jsonArray3.add(jsonObject3);

                                //市
                                JSONObject jsonObject2 = new JSONObject();
                                jsonObject2.put("code", cityCode);
                                jsonObject2.put("codeName", cityName);
                                jsonObject2.put("children", jsonArray3);
//                                JSONArray jsonArray2 = new JSONArray();
//                                jsonArray2.add(jsonObject2);
                                city_children.add(jsonObject2);
                                break outer;//添加了建筑数据后直接跳出循环
                            }
                        }
                    } else { // 省
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("code", provinceCode);
                        jsonObject.put("codeName", provinceName);
                        // 市
                        JSONObject jsonObject2 = new JSONObject();
                        jsonObject2.put("code", cityCode);
                        jsonObject2.put("codeName", cityName);
                        JSONArray jsonArray2 = new JSONArray();
                        jsonArray2.add(jsonObject2);
                        //区
                        JSONObject jsonObject3 = new JSONObject();
                        jsonObject3.put("code", areaCode);
                        jsonObject3.put("codeName", areaName);
                        jsonObject3.put("children", jsonArray4);
                        JSONArray jsonArray3 = new JSONArray();
                        jsonArray3.add(jsonObject3);

                        jsonObject.put("children", jsonArray2);
                        jsonObject2.put("children", jsonArray3);
                        jsonArray.add(jsonObject);
                        break outer;//添加了建筑数据后直接跳出循环
                    }
                }
            } else { //第一次循环
                // 省
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("code", provinceCode);
                jsonObject.put("codeName", provinceName);
                // 市
                JSONObject jsonObject2 = new JSONObject();
                jsonObject2.put("code", cityCode);
                jsonObject2.put("codeName", cityName);
                JSONArray jsonArray2 = new JSONArray();
                jsonArray2.add(jsonObject2);

                //区
                JSONObject jsonObject3 = new JSONObject();
                jsonObject3.put("code", areaCode);
                jsonObject3.put("codeName", areaName);
                jsonObject3.put("children", jsonArray4);
                JSONArray jsonArray3 = new JSONArray();
                jsonArray3.add(jsonObject3);

                jsonObject.put("children", jsonArray2);
                jsonObject2.put("children", jsonArray3);

                jsonArray.add(jsonObject);
            }
        }


    }

    private JSONObject existJSONArray(String code, JSONArray arrays) {
        for (int i = 0; i < arrays.size(); i++) {
            Object o = arrays.get(i);
            if (o.getClass().equals(BuildingTree.class))
                continue;
            JSONObject jsonObject = arrays.getJSONObject(i);
            if (jsonObject.getString("code").equals(code))
                return jsonObject;
        }
        return null;
    }

    /**
     * 生成9位随机数据id
     *
     * @return
     */
    private String genBuildingId() {
        boolean flag = true;
        String id = "";
        while (flag) { // 生成设备编号，如果数据库中存在则继续生成
            id = OrderldUtil.getRandomStr(9);
            int exists = fasBuildingMapper.existsBuildingId(id);
            if (exists == 0) {
                flag = false;
            }
        }
        return id;
    }


}
